#ifndef __RTSP_H
#define __RTSP_H

#include <sys/epoll.h>
#include <string.h>
#include <iostream>
#include <string>
#include <vector>
#include <map>
#include <functional>
#include <memory>
#include <thread>
#include <mutex>
#include <condition_variable>

#define RTP_PORT_VEDIO 8550
#define RTCP_PORT_VEDIO 8551
#define RTP_PORT_AUDIO 8552
#define RTCP_PORT_AUDIO 8553

typedef std::function<void(void *)> mfunc;

struct m_event
{
    m_event()
        : fd(-1)
        , callback(nullptr)
        , ev_datas(nullptr)
        , message(nullptr)
        , message_len(0)
        , rtsp_method("")
    {
    }

    int fd;
    int epoll_fd;
    mfunc callback;
    m_event *ev_datas;
    char *message;
    uint16_t message_len;
    std::string rtsp_method;
};

class RtspServer
{
public:
    RtspServer();
    ~RtspServer();

    void init();
    void run();

    void accept_connect(void *arg);
    void read_data(void *arg);
    void write_data(void *arg);
    std::string parse_request(const std::string &str, int clnt_fd, std::string* type);
    std::vector<std::string> split_string(const std::string &str, const std::string &pattern);

private:
    void play_h264(int clnt_fd, uint16_t rtp_port);
    void play_aac(int clnt_fd, uint16_t rtp_port);

private:
    int _epoll_fd;
    epoll_event _events[1024];
    m_event _ev_datas[1050];
    std::map<int, std::string> _ipmap;
    //std::map<std::string, std::string> _clntports;

    std::unique_ptr<std::thread> _h264_thread;
    std::unique_ptr<std::thread> _acc_thread;
    std::mutex _mtx;
    std::condition_variable _cond;
};

#endif